package com.imdroid.lite.activities;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationManager;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.os.Vibrator;
import android.text.Html;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SubMenu;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.GeoPoint;
import com.baidu.mapapi.ItemizedOverlay;
import com.baidu.mapapi.MKAddrInfo;
import com.baidu.mapapi.MKBusLineResult;
import com.baidu.mapapi.MKDrivingRouteResult;
import com.baidu.mapapi.MKLocationManager;
import com.baidu.mapapi.MKMapViewListener;
import com.baidu.mapapi.MKPlanNode;
import com.baidu.mapapi.MKPoiResult;
import com.baidu.mapapi.MKSearch;
import com.baidu.mapapi.MKSearchListener;
import com.baidu.mapapi.MKSuggestionResult;
import com.baidu.mapapi.MKTransitRouteResult;
import com.baidu.mapapi.MKWalkingRouteResult;
import com.baidu.mapapi.MapActivity;
import com.baidu.mapapi.MapController;
import com.baidu.mapapi.MapView;
import com.baidu.mapapi.MyLocationOverlay;
import com.baidu.mapapi.Overlay;
import com.baidu.mapapi.OverlayItem;
import com.baidu.mapapi.Projection;
import com.baidu.mapapi.RouteOverlay;
import com.imdroid.carac.audioCodec.StreamListener;
import com.imdroid.carac.audioCodec.UDPMicrophone;
import com.imdroid.carac.audioCodec.UDPSpeaker;
import com.imdroid.lite.IMDroid;
import com.imdroid.lite.R;
import com.imdroid.lite.activities.TeamTalkHistoryActivity.TalkCollection;
import com.imdroid.lite.model.Team;
import com.imdroid.lite.model.TeamMember;
import com.imdroid.lite.model.TeamTalk;
import com.imdroid.lite.net.udp.UDPSendUtilRealtime;
import com.imdroid.lite.net.udp.UDPServer;
import com.imdroid.lite.process.PlaySoundProcess;
import com.imdroid.lite.process.ProcessFactory;
import com.imdroid.lite.process.TeamProcess;

/**
 * The team map activity
 * 
 */
public class TeamMapActivity extends MapActivity {
	/**
	 * The tag of the map activity
	 */
	private static final String TAG = "TeamMapActivity";
	/**
	 * The map view;
	 */
	private MapView mapView;
	/**
	 * The map manager
	 */
	private BMapManager bMapManager;
	/**
	 * The controller of the map;
	 */
	private MapController mapController;
	/**
	 * The location manager
	 */
	private MKLocationManager locationManager;
	/**
	 * The MK Search
	 */
	private MKSearch mKSearch;
	/**
	 * The team leader overy lay
	 */
	private TeamLeaderOverlay teamLeaderOverlay = null;
	/**
	 * The team leader overy lay
	 */
	private TeamMemberOverlay teamMemberOverlay = null;
	/**
	 * The team leader overy lay
	 */
	private DestinationOverlay destinationOverlay = null;
	/**
	 * The route overlay
	 */
	private RouteOverlay routeOverlay = null;
	/**
	 * The default zoon level
	 */
	private static final int defailtZoomLevel = 15;
	/**
	 * if current status is in navigation - it will lock my position
	 */
	private static boolean isNavigation = true;
	/**
	 * The current location
	 */
	private static Location currentLocation;
	/**
	 * The active instance
	 */
	public static TeamMapActivity instance = null;
	/**
	 * The message handler
	 */
	private Handler messageHandler;
	/**
	 * The wake lock to control the screen
	 */
	PowerManager.WakeLock wakeLock;
	/**
	 * The team talks
	 */
	private Collection<TeamTalk> teamTalks = new TalkCollection<TeamTalk>();
	/**
	 * The events
	 */
	// exit the map and team
	public static final int EVENT_TEAM_EXIT = 0x1001;
	// refresh all the team member
	public static final int EVENT_TEAM_REFRESH = 0x1002;
	// Update all the team member position
	public static final int EVENT_TEAM_UPDATE = 0x1003;
	// Sent location to other members
	public static final int EVENT_TEAM_SEND_LOCATION = 0x1004;
	// Sent location to other members
	public static final int EVENT_TEAM_SEND_DEST_NO_ROUTE = 0x1005;
	// Sent location to other members
	public static final int EVENT_TEAM_SEND_DEST_WITH_ROUTE = 0x1006;
	// Receive the destination
	public static final int EVENT_TEAM_RECEIVE_LOCATION = 0x1008;
	// Make animations when recording voice.
	public static final int EVENT_CHANGE_CALL_ANIM_ICON = 0x1010;
	// Make animations when recording voice.
	public static final int EVENT_ERROR = 0x9990;

	// the animation icons.
	private static final int[] anim_icons = { R.drawable.recording0,
			R.drawable.recording1, R.drawable.recording2, R.drawable.recording3 };
	// the animation timer.
	private Timer animTimer;
	private TimerTask animTask;
	private boolean paused;
	private boolean bupdateMe = true;

	/**
	 * If the map in active status
	 */
	private boolean active;
	/**
	 * If the map in mute mode
	 */
	private boolean mute = false;
	/**
	 * If the map in line mode
	 */
	private boolean line = true;
	/**
	 * The the first move the screen;
	 */
	private boolean hasMove = false;
	/**
	 * if show member list
	 */
	private boolean showMember = true;

	/**
	 * The last time when end a recording.
	 */
	private static long lastEndRecordTime;
	/**
	 * When the record ends, need to wait at least this time interval to start
	 * another.
	 */
	private static long recordStopInterval = 1000;

	// arrow for members direction
	private int intDirection = 8;
	private int[] arrayHeading = new int[] { 22, 67, 112, 157, 202, 247, 292,
			337 };
	private final Drawable arrow_Member[] = new Drawable[intDirection + 1];
	private final Drawable arrow_Member_Lite[] = new Drawable[intDirection + 1];
	private final Drawable arrow_Leader[] = new Drawable[intDirection + 1];
	private final Drawable arrow_Leader_Lite[] = new Drawable[intDirection + 1];
	private final int arrow_Me[] = new int[intDirection + 1];
	private final int arrow_Me_Member[] = new int[intDirection + 1];
	private int arrowWidth, arrowHeight;

	/**
	 * The gesture detector
	 */
	private GestureDetector gestureDetector;

	// private AudioManager am;
	// private SensorManager sm;
	// private SensorEventListener sel;

	/**
	 * The tts engine
	 */
	// private TextToSpeech tts;
	/*
	 * (non-Javadoc)
	 * 
	 * @see com.baidu.mapapi.MapActivity#onCreate(android.os.Bundle)
	 */
	public void onCreate(Bundle savedInstanceState) {
		// 初始化界面
		super.onCreate(savedInstanceState);
		setContentView(R.layout.team_map_main);

		// 设置各个按钮
		mapView = (MapView) this.findViewById(R.id.team_map_main);
		Button callButton = ((Button) this.findViewById(R.id.team_map_call));
		callButton.setOnTouchListener(callOnTouchListener);

		// 初始化hander
		initHandler();
		instance = this;
		setActive(true);

		// 初始化地图
		IMDroid app = (IMDroid) this.getApplication();
		bMapManager = app.mBMapMan;
		super.initMapActivity(app.mBMapMan);
		bMapManager.start();

		// 初始化location manager
		locationManager = app.mBMapMan.getLocationManager();
		locationManager.enableProvider(MKLocationManager.MK_GPS_PROVIDER);
		locationManager.enableProvider(MKLocationManager.MK_NETWORK_PROVIDER);

		// 初始化MKSearch类:
		mKSearch = new MKSearch();
		mKSearch.init(bMapManager, mapSearchListener);

		// 设置地图中心
		isNavigation = true;
		mapController = mapView.getController();
		mapController.setZoom(defailtZoomLevel);
		mapView.setDoubleClickZooming(true);
		mapView.setDrawOverlayWhenZooming(true);
		mapView.setBuiltInZoomControls(false);
		mapView.setLongClickable(true);
		mapView.regMapViewListener(app.mBMapMan, mapViewListener);
		gestureDetector = new GestureDetector(this, new MapGestureListener());
		mapView.setOnTouchListener(new OnTouchListener() {
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				gestureDetector.onTouchEvent(event);
				return false;
			}
		});

		// 设置图层
		teamLeaderOverlay = new TeamLeaderOverlay(this, mapView);
		teamLeaderOverlay.enableMyLocation();
		teamLeaderOverlay.enableCompass();
		teamMemberOverlay = new TeamMemberOverlay(R.drawable.map_car_friend);
		destinationOverlay = new DestinationOverlay();
		// 首次的定位
		teamLeaderOverlay.runOnFirstFix(new Runnable() {
			public void run() {
				mapController.setCenter(teamLeaderOverlay.getMyLocation());
			}
		});
		mapView.getOverlays().add(teamLeaderOverlay);
		mapView.getOverlays().add(teamMemberOverlay);
		mapView.getOverlays().add(destinationOverlay);
		mapView.setFocusable(true);

		// 启动通知服务，连接服务器
		// startService(new Intent(this, NotificationService.class));
		try {
			UDPServer.startup();
		} catch (Exception e) {
			e.printStackTrace();
		}

		UDPSpeaker.start();
		// 检查音量是否足够
		checkAudio();
		// 检查GPS是否打开
		checkGPS();
		// 初始化箭头
		initArrow();
		// setup sensor
		// setupSensor();
		// 初始动画定时器
		animTimer = new Timer();
	}

	// private void setupSensor(){
	// am = (AudioManager) getSystemService(AUDIO_SERVICE);
	// sm = (SensorManager) getSystemService(SENSOR_SERVICE);
	// sel = new SensorEventListener(){
	// @Override
	// public void onAccuracyChanged(Sensor sensor, int accuracy) {
	//
	// }
	//
	// @Override
	// public void onSensorChanged(SensorEvent event) {
	// float[] values = event.values;
	// if(values != null && event.sensor.getType() == Sensor.TYPE_PROXIMITY) {
	// if(values[0] <= 3.0) {
	// am.setMode(AudioManager.MODE_IN_CALL);
	// } else {
	// am.setMode(AudioManager.MODE_NORMAL);
	// }
	// }
	// }
	// };
	// sm.registerListener(sel, sm.getDefaultSensor(Sensor.TYPE_PROXIMITY),
	// SensorManager.SENSOR_DELAY_UI);
	// }

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.baidu.mapapi.MapActivity#onResume()
	 */
	protected void onResume() {
		paused = false;
		// 设置不锁屏，得到wake log
		// PowerManager pm = (PowerManager)
		// getSystemService(Context.POWER_SERVICE);
		// wakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, this
		// .getClass().getCanonicalName());
		// wakeLock.acquire();
		// 接触锁屏
		// if (bMapManager != null) {
		// bMapManager.start();
		// }
		setActive(true);
		// 刷新成员列表
		messageHandler.sendEmptyMessage(EVENT_TEAM_REFRESH);
		// 如有目的地且要查找路线的
		Team team = Team.getCurrentTeam();
		if (team.isSearchRoute())
			messageHandler.sendEmptyMessage(EVENT_TEAM_REFRESH);
		// 如果是队长，则显示下发目的地的按钮
		ImageButton button = (ImageButton) this
				.findViewById(R.id.team_map_dest);
		if (team.getTeamId() == IMDroid.getUser().getUser_id())
			button.setVisibility(View.VISIBLE);
		else
			button.setVisibility(View.GONE);

		ScrollView scrollView = (ScrollView) findViewById(R.id.team_map_member_sv_float);
		TextView textView = (TextView) findViewById(R.id.team_map_member_tv_float);
		if (Team.getCurrentTeam().getTeamName() != ""
				&& !Team.getCurrentTeam().getTeamName().equals("")) {
			textView.setText(Team.getCurrentTeam().getTeamName());
		}
		scrollView.setVisibility(View.VISIBLE);

		super.onResume();

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.baidu.mapapi.MapActivity#onPause()
	 */
	protected void onPause() {
		paused = true;
		// Enable location manager
		// locationManager.disableProvider(MKLocationManager.MK_GPS_PROVIDER);
		// locationManager.disableProvider(MKLocationManager.MK_NETWORK_PROVIDER);

		// 接触锁屏
		// if (bMapManager != null) {
		// bMapManager.stop();
		// }
		// if (wakeLock != null)
		// wakeLock.release();

		super.onPause();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.baidu.mapapi.MapActivity#onDestroy()
	 */
	protected void onDestroy() {
		super.onDestroy();

		// sm.unregisterListener(sel);
		// sm = null;
		// am.setMode(AudioManager.MODE_NORMAL);
		// am = null;
		// sel = null;

		// 设置状态
		setActive(false);
		if (bMapManager != null)
			bMapManager.stop();
		if (animTimer != null) {
			animTimer.cancel();
			animTimer = null;
		}

		if (animTask != null) {
			animTask.cancel();
			animTask = null;
		}

		// 关闭通知服务，与服务器断开连接
		UDPServer.shutdown();
		// Intent i = new Intent(Intent.ACTION_RUN);
		// i.setClass(this, NotificationService.class);
		// this.stopService(i);

		UDPSpeaker.stop();
		UDPMicrophone.stopRecording();

		((AudioManager) getSystemService(AUDIO_SERVICE))
				.setMode(AudioManager.MODE_NORMAL);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onPrepareOptionsMenu(android.view.Menu)
	 */
	public boolean onPrepareOptionsMenu(Menu menu) {
		menu.clear();
		Team team = Team.getCurrentTeam();

		SubMenu sbmTemp;
		if (team != null) {
			if (!(team.getDestinationLat() == 0 && team.getDestinationLon() == 0)) {
				sbmTemp = menu.addSubMenu(Menu.NONE, 0, Menu.NONE,
						this.getString(R.string.team_map_dest));
			}

			for (TeamMember member : team.getMembers().values()) {
				// team leader
				sbmTemp = menu.addSubMenu(Menu.NONE, member.getId(), Menu.NONE,
						member.getDisplayName());
				// team leader
				if (member.getId() == team.getTeamId()) {
					if (member.getId() == IMDroid.getUser().getUser_id()) {
						sbmTemp.setIcon(R.drawable.arrow_me_n);
					} else {
						// client & team leader
						if (member.getDeviceType().equals("1")) {
							sbmTemp.setIcon(R.drawable.arrow_leader_n);
						} else {// lite & team leader
							sbmTemp.setIcon(R.drawable.arrow_leader_lite_n);
						}
					}
				} else {// team member
					if (member.getId() == IMDroid.getUser().getUser_id()) {
						sbmTemp.setIcon(R.drawable.arrow_me_member_n);
					} else {
						if (member.getDeviceType().equals("1")) {
							sbmTemp.setIcon(R.drawable.arrow_member_n);
						} else {
							sbmTemp.setIcon(R.drawable.arrow_member_lite_n);
						}
					}
				}
			}
		}

		// if (team != null) {
		// // 目的地
		// if (!(team.getDestinationLat() == 0 && team.getDestinationLon() ==
		// 0))
		// menu.add(Menu.NONE, 0, Menu.NONE,
		// this.getString(R.string.team_map_dest));
		//
		// int leaderId = -1;
		// // 加入队长的位置
		// if (team.getTeamLeader() != null
		// && team.getTeamId() != team.getTeamLeader().getId()) {
		// leaderId = team.getTeamLeader().getId();
		// Log.d(TAG, "LEADER---" + team.getTeamLeader());
		// menu.add(Menu.NONE, team.getTeamLeader().getId(), Menu.NONE,
		// team.getTeamLeader().getDisplayName());
		// }
		// // 加入各个Member的位置
		// for (TeamMember member : team.getMembers().values())
		// if (member.getId() != IMDroid.getUser().getUser_id()
		// && member.getId() != leaderId)
		// menu.add(Menu.NONE, member.getId(), Menu.NONE,
		// member.getDisplayName());
		// // 显示或隐藏成员列表
		// menu.add(
		// Menu.NONE,
		// -1,
		// Menu.NONE,
		// this.getResources().getString(
		// showMember ? R.string.team_hide_member_text
		// : R.string.team_show_member_text));
		// }

		return super.onPrepareOptionsMenu(menu);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
	 */
	public boolean onOptionsItemSelected(MenuItem item) {
		// 如果是导航状态，则先解锁
		if (isNavigation)
			locateMe(this.findViewById(R.id.team_map_location));
		int member_id = item.getItemId();
		Log.d(TAG, "search " + member_id);
		Team team = Team.getCurrentTeam();
		// 如果是定位目的度
		if (member_id == 0) {
			if (!(team.getDestinationLat() == 0 && team.getDestinationLon() == 0))
				mapController.setCenter(new GeoPoint((int) (team
						.getDestinationLat() * 1E6), (int) (team
						.getDestinationLon() * 1E6)));

		}

		// 如果是定位队员们
		if (member_id > 0) {
			TeamMember member = team.getMembers().get(member_id);
			if (member != null) {
				if (member.getLat() == 0 && member.getLat() == 0) {
					// 如果没有定位，
					String mess = this.getString(R.string.team_no_positon);
					mess = mess.replace("%1", member.getDisplayName());
					Toast.makeText(this, mess, Toast.LENGTH_SHORT).show();
				} else {
					mapController.setCenter(new GeoPoint(
							(int) (member.getLat() * 1E6), (int) (member
									.getLon() * 1E6)));
				}
			}
		}
		if (member_id == -1) {
			showMember = !showMember;
			showOrHideMember(showMember);
		}
		return super.onOptionsItemSelected(item);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onKeyDown(int, android.view.KeyEvent)
	 */
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		// System.out.println("Key --> headset ? " + (keyCode ==
		// KeyEvent.KEYCODE_HEADSETHOOK));
		// 退出前确认
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			AlertDialog.Builder buidler = new AlertDialog.Builder(this);
			buidler.setMessage(R.string.team_exit_confirm);

			buidler.setPositiveButton("Ok", new OnClickListener() {
				public void onClick(DialogInterface arg0, int arg1) {
					messageHandler.sendEmptyMessage(EVENT_TEAM_EXIT);
					// 回到主界面
					// TeamMapActivity.this.startActivity(new Intent(
					// TeamMapActivity.this, MainActivity.class));
					TeamMapActivity.this.finish();
				}
			});
			buidler.setNegativeButton("Cancel", new OnClickListener() {
				public void onClick(DialogInterface arg0, int arg1) {
					arg0.dismiss();
				}
			});

			buidler.show();
			return true;
			// } else if(){
			// volumeDown();
			// return true;
		}
		return super.onKeyDown(keyCode, event);
	}

	/*
	 * initiate arrow for member's direction
	 */
	private void initArrow() {

		// team member
		arrow_Member[0] = getResources().getDrawable(R.drawable.arrow_member_n);
		arrow_Member[1] = getResources().getDrawable(R.drawable.arrow_member_0);
		arrow_Member[2] = getResources()
				.getDrawable(R.drawable.arrow_member_45);
		arrow_Member[3] = getResources()
				.getDrawable(R.drawable.arrow_member_90);
		arrow_Member[4] = getResources().getDrawable(
				R.drawable.arrow_member_135);
		arrow_Member[5] = getResources().getDrawable(
				R.drawable.arrow_member_180);
		arrow_Member[6] = getResources().getDrawable(
				R.drawable.arrow_member_225);
		arrow_Member[7] = getResources().getDrawable(
				R.drawable.arrow_member_270);
		arrow_Member[8] = getResources().getDrawable(
				R.drawable.arrow_member_315);

		// team member for lite
		arrow_Member_Lite[0] = getResources().getDrawable(
				R.drawable.arrow_member_lite_n);
		arrow_Member_Lite[1] = getResources().getDrawable(
				R.drawable.arrow_member_lite_0);
		arrow_Member_Lite[2] = getResources().getDrawable(
				R.drawable.arrow_member_lite_45);
		arrow_Member_Lite[3] = getResources().getDrawable(
				R.drawable.arrow_member_lite_90);
		arrow_Member_Lite[4] = getResources().getDrawable(
				R.drawable.arrow_member_lite_135);
		arrow_Member_Lite[5] = getResources().getDrawable(
				R.drawable.arrow_member_lite_180);
		arrow_Member_Lite[6] = getResources().getDrawable(
				R.drawable.arrow_member_lite_225);
		arrow_Member_Lite[7] = getResources().getDrawable(
				R.drawable.arrow_member_lite_270);
		arrow_Member_Lite[8] = getResources().getDrawable(
				R.drawable.arrow_member_lite_315);

		// team leader
		arrow_Leader[0] = getResources().getDrawable(R.drawable.arrow_leader_n);
		arrow_Leader[1] = getResources().getDrawable(R.drawable.arrow_leader_0);
		arrow_Leader[2] = getResources()
				.getDrawable(R.drawable.arrow_leader_45);
		arrow_Leader[3] = getResources()
				.getDrawable(R.drawable.arrow_leader_90);
		arrow_Leader[4] = getResources().getDrawable(
				R.drawable.arrow_leader_135);
		arrow_Leader[5] = getResources().getDrawable(
				R.drawable.arrow_leader_180);
		arrow_Leader[6] = getResources().getDrawable(
				R.drawable.arrow_leader_225);
		arrow_Leader[7] = getResources().getDrawable(
				R.drawable.arrow_leader_270);
		arrow_Leader[8] = getResources().getDrawable(
				R.drawable.arrow_leader_315);
		// Me
		arrow_Me[0] = R.drawable.arrow_me_n;
		arrow_Me[1] = R.drawable.arrow_me_0;
		arrow_Me[2] = R.drawable.arrow_me_45;
		arrow_Me[3] = R.drawable.arrow_me_90;
		arrow_Me[4] = R.drawable.arrow_me_135;
		arrow_Me[5] = R.drawable.arrow_me_180;
		arrow_Me[6] = R.drawable.arrow_me_225;
		arrow_Me[7] = R.drawable.arrow_me_270;
		arrow_Me[8] = R.drawable.arrow_me_315;

		// Me as member
		arrow_Me_Member[0] = R.drawable.arrow_me_member_n;
		arrow_Me_Member[1] = R.drawable.arrow_me_member_0;
		arrow_Me_Member[2] = R.drawable.arrow_me_member_45;
		arrow_Me_Member[3] = R.drawable.arrow_me_member_90;
		arrow_Me_Member[4] = R.drawable.arrow_me_member_135;
		arrow_Me_Member[5] = R.drawable.arrow_me_member_180;
		arrow_Me_Member[6] = R.drawable.arrow_me_member_225;
		arrow_Me_Member[7] = R.drawable.arrow_me_member_270;
		arrow_Me_Member[8] = R.drawable.arrow_me_member_315;

		// team leader lite
		arrow_Leader_Lite[0] = getResources().getDrawable(
				R.drawable.arrow_leader_lite_n);
		arrow_Leader_Lite[1] = getResources().getDrawable(
				R.drawable.arrow_leader_lite_0);
		arrow_Leader_Lite[2] = getResources().getDrawable(
				R.drawable.arrow_leader_lite_45);
		arrow_Leader_Lite[3] = getResources().getDrawable(
				R.drawable.arrow_leader_lite_90);
		arrow_Leader_Lite[4] = getResources().getDrawable(
				R.drawable.arrow_leader_lite_135);
		arrow_Leader_Lite[5] = getResources().getDrawable(
				R.drawable.arrow_leader_lite_180);
		arrow_Leader_Lite[6] = getResources().getDrawable(
				R.drawable.arrow_leader_lite_225);
		arrow_Leader_Lite[7] = getResources().getDrawable(
				R.drawable.arrow_leader_lite_270);
		arrow_Leader_Lite[8] = getResources().getDrawable(
				R.drawable.arrow_leader_lite_315);

		arrowWidth = arrow_Member[0].getIntrinsicWidth();
		arrowHeight = arrow_Member[0].getIntrinsicHeight();
		for (int i = 0; i < intDirection + 1; i++) {
			arrow_Member[i].setBounds(0, 0, arrowWidth, arrowHeight);
			arrow_Member_Lite[i].setBounds(0, 0, arrowWidth, arrowHeight);
			arrow_Leader[i].setBounds(0, 0, arrowWidth, arrowHeight);
			arrow_Leader_Lite[i].setBounds(0, 0, arrowWidth, arrowHeight);
		}
	}

	/**
	 * The handler of message.
	 */
	@SuppressLint("HandlerLeak")
	private void initHandler() {

		messageHandler = new Handler() {
			public void handleMessage(Message msg) {

				try {
					processedMessage(msg);
				} catch (Exception e) {
					e.printStackTrace();
					Toast.makeText(IMDroid.getAppContext(), e.getMessage(),
							Toast.LENGTH_SHORT).show();
				}
			}
		};

	}

	/**
	 * Get the handler object;
	 * 
	 * @return
	 */
	public Handler getHandler() {
		return messageHandler;
	}

	/**
	 * Get the current location
	 * 
	 * @return the currentLocation
	 */
	public Location getCurrentLocation() {
		return currentLocation;
	}

	/**
	 * Get the Geo String of the current location.
	 * 
	 * @return the Geo String of the current location.
	 */
	public String getCurrentGeoString() {
		return (currentLocation != null) ? Math.round((currentLocation
				.getLatitude() * 1000))
				+ "--"
				+ Math.round((currentLocation.getLongitude() * 1000)) : "--";
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.baidu.mapapi.MapActivity#isRouteDisplayed()
	 */
	protected boolean isRouteDisplayed() {
		return false;
	}

	/**
	 * Get if the activity is active
	 * 
	 * @return the active
	 */
	public boolean isActive() {
		return active;
	}

	/**
	 * Set if the activity is active
	 * 
	 * @param active
	 *            the active to set
	 */
	public void setActive(boolean active) {
		this.active = active;
	}

	/**
	 * Get if it is in mute mode
	 * 
	 * @return the mute
	 */
	public boolean isMute() {
		return mute;
	}

	/**
	 * Set if it is in mute mode
	 * 
	 * @param mute
	 *            the mute to set
	 */
	public void setMute(boolean mute) {
		this.mute = mute;
		if (mute) {
			((AudioManager) getSystemService(AUDIO_SERVICE))
					.setMode(AudioManager.MODE_IN_CALL);
		} else {
			((AudioManager) getSystemService(AUDIO_SERVICE))
					.setMode(AudioManager.MODE_NORMAL);
		}
	}

	/**
	 * Get the team talks
	 * 
	 * @return the teamTalks
	 */
	public Collection<TeamTalk> getTeamTalks() {
		return teamTalks;
	}

	/**
	 * The event clicking the button zoomin
	 * 
	 * @param view
	 *            the button of zoom in
	 */
	public void zoomIn(View view) {
		if (!mapController.zoomIn())
			Toast.makeText(this, this.getString(R.string.team_map_zoom_in_max),
					Toast.LENGTH_SHORT).show();
	}

	/**
	 * The event clicking the button zoom out
	 * 
	 * @param view
	 *            the button of zoom out
	 */
	public void zoomOut(View view) {
		if (!mapController.zoomOut())
			Toast.makeText(this,
					this.getString(R.string.team_map_zoom_out_max),
					Toast.LENGTH_SHORT).show();
	}

	/**
	 * The event clicking the button zoom out
	 * 
	 * @param view
	 *            the buttobn of location
	 */
	public void locateMe(View view) {
		try {
			teamLeaderOverlay.enableCompass();
			teamLeaderOverlay.enableMyLocation();
			if (teamLeaderOverlay.getMyLocation() != null) {
				mapController.setCenter(teamLeaderOverlay.getMyLocation());
			}
			ImageButton button = (ImageButton) view;
			button.setImageResource(R.drawable.self_centered_on);
			// 重置状态
			isNavigation = !isNavigation;
			bupdateMe = true;

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Mute the sound
	 * 
	 * @param view
	 *            the button of mute
	 */
	public void mute(View view) {
		setMute(!mute);
		ImageButton button = (ImageButton) view;
		button.setImageResource(mute ? R.drawable.mute_on : R.drawable.mute_off);
	}

	/**
	 * Show / Hide the line
	 * 
	 * @param view
	 *            the button of mute
	 */
	public void line(View view) {
		line = !line;
		ImageButton button = (ImageButton) view;
		button.setImageResource(line ? R.drawable.btn_icon_ly
				: R.drawable.btn_icon_ln);
	}

	/**
	 * 历史对话
	 * 
	 * @param view
	 */
	public void teamTalk(View view) {
		clearNew();
		startActivity(new Intent(this, TeamTalkHistoryActivity.class));
	}

	/**
	 * 清空新信息提示
	 */
	public void clearNew() {
		// messageHandler.post(new Runnable() {
		// public void run() {
		// findViewById(R.id.tips).setVisibility(View.GONE);
		// }
		// });
	}

	/**
	 * 添加信息提示
	 */
	public void addNewTips() {
		// messageHandler.post(new Runnable() {
		// public void run() {
		// findViewById(R.id.tips).setVisibility(View.VISIBLE);
		// }
		// });
	}

	/**
	 * Set the destination
	 * 
	 * @param view
	 *            the button of setting destination
	 */
	public void setDestination(View view) {
		final EditText destination = new EditText(this);
		destination.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);

		AlertDialog.Builder buidler = new AlertDialog.Builder(
				TeamMapActivity.this);
		buidler.setTitle(R.string.team_map_destination_name);
		buidler.setIcon(android.R.drawable.ic_dialog_info);
		buidler.setView(destination);

		// 按钮 - 是，查找地址
		buidler.setPositiveButton(
				TeamMapActivity.this.getString(R.string.team_btn_search),
				new OnClickListener() {
					public void onClick(DialogInterface arg0, int arg1) {
						if (destination.getText().toString() != null
								&& destination.getText().toString().length() > 0)
							mKSearch.suggestionSearch(destination.getText()
									.toString());
						else
							Toast.makeText(
									TeamMapActivity.this,
									TeamMapActivity.this
											.getString(R.string.team_map_destination_name_empty),
									Toast.LENGTH_SHORT).show();
					}
				});
		// 按钮 - 否
		buidler.setNegativeButton(
				TeamMapActivity.this.getString(R.string.team_btn_cancel),
				new OnClickListener() {
					public void onClick(DialogInterface arg0, int arg1) {
					}
				});

		buidler.show();
	}

	private OnTouchListener callOnTouchListener = new OnTouchListener() {
		/*
		 * (non-Javadoc)
		 * 
		 * @see android.view.View.OnTouchListener#onTouch(android.view.View,
		 * android.view.MotionEvent)
		 */
		public boolean onTouch(View v, MotionEvent event) {
			clearNew();
			if (event.getAction() == MotionEvent.ACTION_DOWN) {
				// 并发送一次地址
				messageHandler.sendEmptyMessage(EVENT_TEAM_SEND_LOCATION);
			}
			if (Team.getCurrentTeam() != null) {
				View callView = TeamMapActivity.this
						.findViewById(R.id.team_map_image_record);
				if (event.getAction() == MotionEvent.ACTION_DOWN) {
					// when interval time is not enough
					if (System.currentTimeMillis() - lastEndRecordTime < recordStopInterval)
						return true;
					// 按键按下震动
					((Vibrator) IMDroid.getAppContext().getSystemService(
							Context.VIBRATOR_SERVICE)).vibrate(200);

					callView.setVisibility(View.VISIBLE);
					// 对讲,开始录音
					if (!TeamCallHelper.isRecording
							&& !TeamCallHelper.isStopping)
						TeamCallHelper.startRecording();
				}
				if (event.getAction() == MotionEvent.ACTION_UP) {
					lastEndRecordTime = System.currentTimeMillis();
					callView.setVisibility(View.GONE);
					// 对讲
					if (TeamCallHelper.isRecording
							&& !TeamCallHelper.isStopping)
						TeamCallHelper.stopRecording();
				}
			}
			return true;
		}
	};
	/**
	 * The map view listener
	 */
	private MKMapViewListener mapViewListener = new MKMapViewListener() {
		/*
		 * (non-Javadoc)
		 * 
		 * @see com.baidu.mapapi.MKMapViewListener#onMapMoveFinish()
		 */
		public void onMapMoveFinish() {
			// 主动拖动时，就解锁“以我为中心”
			if (isNavigation && !hasMove) {
				ImageButton button = (ImageButton) findViewById(R.id.team_map_location);
				button.setImageResource(R.drawable.self_centered_off);
				isNavigation = false;
			}
			hasMove = false;
		}
	};

	/**
	 * The gesture detctor
	 */
	private class MapGestureListener extends SimpleOnGestureListener {
		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * android.view.GestureDetector.SimpleOnGestureListener#onLongPress(
		 * android.view.MotionEvent)
		 */
		public void onLongPress(MotionEvent e) {
			// 只有队长可以发送地址
			if (Team.getCurrentTeam() == null
					|| Team.getCurrentTeam().getTeamId() != IMDroid.getUser()
							.getUser_id())
				return;
			final GeoPoint myGeoPoint = mapView.getProjection().fromPixels(
					(int) e.getX(), (int) e.getY());

			if (myGeoPoint == null)
				return;
			// 弹出对话框
			AlertDialog.Builder buidler = new AlertDialog.Builder(
					TeamMapActivity.this);
			buidler.setIcon(android.R.drawable.ic_dialog_info);
			buidler.setMessage(R.string.team_map_confirm_dest);
			// 按钮 - 是，并重新规划路线
			buidler.setPositiveButton(TeamMapActivity.this
					.getString(R.string.team_map_confirm_dest_yy),
					new OnClickListener() {
						public void onClick(DialogInterface arg0, int arg1) {
							// 设置目的地
							Message msg = new Message();
							msg.what = EVENT_TEAM_SEND_DEST_WITH_ROUTE;
							msg.obj = myGeoPoint;
							// 发送目的地给其他队友
							messageHandler.sendMessage(msg);
						}
					});
			// 按钮 - 是，但是不规划路线
			buidler.setNeutralButton(TeamMapActivity.this
					.getString(R.string.team_map_confirm_dest_yr),
					new OnClickListener() {
						public void onClick(DialogInterface arg0, int arg1) {
							// 设置目的地
							Message msg = new Message();
							msg.what = EVENT_TEAM_SEND_DEST_NO_ROUTE;
							msg.obj = myGeoPoint;
							// 发送目的地给其他队友
							messageHandler.sendMessage(msg);
						}
					});
			// 按钮 - 否
			buidler.setNegativeButton(TeamMapActivity.this
					.getString(R.string.team_map_confirm_dest_n),
					new OnClickListener() {
						public void onClick(DialogInterface arg0, int arg1) {
							arg0.dismiss();
						}
					});

			buidler.show();
		}

		public boolean onDown(MotionEvent e) {
			bupdateMe = false;
			ImageButton button = (ImageButton) findViewById(R.id.team_map_location);
			button.setImageResource(R.drawable.self_centered_off);
			return false;
		}
	}

	/**
	 * The seach listener of the map
	 */
	private MKSearchListener mapSearchListener = new MKSearchListener() {
		/**
		 * The name of the destination;
		 */
		private String destinationAddress;
		/**
		 * If need the search the route.
		 */
		private boolean searchRoute;

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.MKSearchListener#onGetAddrResult(com.baidu.mapapi
		 * .MKAddrInfo, int)
		 */
		public void onGetAddrResult(MKAddrInfo result, int error) {
			if (error != 0) {
				Toast.makeText(TeamMapActivity.this, "Error Code:" + error,
						Toast.LENGTH_LONG).show();
				return;
			}
			Log.d(TAG, "Lat:" + result.geoPt.getLatitudeE6() / 1e6 + "Lon:"
					+ result.geoPt.getLongitudeE6() / 1e6);
			// 设置目的地
			Message msg = new Message();

			msg.what = searchRoute ? EVENT_TEAM_SEND_DEST_WITH_ROUTE
					: EVENT_TEAM_SEND_DEST_NO_ROUTE;
			msg.obj = result.geoPt;
			// 发送目的地给其他队友
			messageHandler.sendMessage(msg);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.MKSearchListener#onGetBusDetailResult(com.baidu.
		 * mapapi.MKBusLineResult, int)
		 */
		public void onGetBusDetailResult(MKBusLineResult arg0, int arg1) {

		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.MKSearchListener#onGetDrivingRouteResult(com.baidu
		 * .mapapi.MKDrivingRouteResult, int)
		 */
		public void onGetDrivingRouteResult(MKDrivingRouteResult arg0, int arg1) {
			if (arg0 == null) {
				return;
			}
			if (routeOverlay != null)
				mapView.getOverlays().remove(routeOverlay);
			routeOverlay = new RouteOverlay(TeamMapActivity.this, mapView);
			// 只选择第一种
			routeOverlay.setData(arg0.getPlan(0).getRoute(0));
			mapView.getOverlays().add(routeOverlay);
			mapView.invalidate();
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.MKSearchListener#onGetPoiResult(com.baidu.mapapi
		 * .MKPoiResult, int, int)
		 */
		public void onGetPoiResult(MKPoiResult arg0, int arg1, int arg2) {

		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.MKSearchListener#onGetSuggestionResult(com.baidu
		 * .mapapi.MKSuggestionResult, int)
		 */
		public void onGetSuggestionResult(MKSuggestionResult result, int iError) {
			// 如果没有找到目的地
			if (iError != 0 || result == null) {
				Toast.makeText(
						TeamMapActivity.this,
						TeamMapActivity.this
								.getString(R.string.team_map_destination_error),
						Toast.LENGTH_LONG).show();
				return;
			}
			// 把目的地组成数组，准备显示选择
			int nSize = result.getSuggestionNum();
			final String[] mStrSuggestions = new String[nSize];
			for (int i = 0; i < nSize; i++)
				mStrSuggestions[i] = result.getSuggestion(i).city + "-"
						+ result.getSuggestion(i).key;
			destinationAddress = null;
			// 弹出对话框
			AlertDialog.Builder buidler = new AlertDialog.Builder(
					TeamMapActivity.this);
			buidler.setTitle(R.string.team_map_destination_name);
			buidler.setIcon(android.R.drawable.ic_dialog_info);
			buidler.setSingleChoiceItems(mStrSuggestions, 0,
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int which) {
							// 记下选择的地址
							destinationAddress = mStrSuggestions[which];

						}
					});
			// 按钮 - 是，但不规划路线
			buidler.setPositiveButton(TeamMapActivity.this
					.getString(R.string.team_map_confirm_dest_yy),
					new OnClickListener() {
						public void onClick(DialogInterface arg0, int arg1) {
							destinationAddress = (destinationAddress != null) ? destinationAddress
									: mStrSuggestions[0];
							// 将地址再转为坐标
							String city = destinationAddress.substring(0,
									destinationAddress.indexOf("-"));
							String key = destinationAddress.substring(
									destinationAddress.indexOf("-"),
									destinationAddress.length());
							searchRoute = true;
							Log.d(TAG, "select key:" + key + "city:" + city);
							mKSearch.geocode(key, city);
						}
					});
			// 按钮 - 是，但不规划路线
			buidler.setNeutralButton(TeamMapActivity.this
					.getString(R.string.team_map_confirm_dest_yr),
					new OnClickListener() {
						public void onClick(DialogInterface arg0, int arg1) {
							destinationAddress = (destinationAddress != null) ? destinationAddress
									: mStrSuggestions[0];

							// 将地址再转为坐标
							String city = destinationAddress.substring(0,
									destinationAddress.indexOf("-"));
							String key = destinationAddress.substring(
									destinationAddress.indexOf("-"),
									destinationAddress.length());
							searchRoute = false;
							Log.d(TAG, "select key:" + key + "city:" + city);
							mKSearch.geocode(key, city);

						}
					});
			// 按钮 - 否
			buidler.setNegativeButton(TeamMapActivity.this
					.getString(R.string.team_map_confirm_dest_n),
					new OnClickListener() {
						public void onClick(DialogInterface arg0, int arg1) {
						}
					});
			buidler.show();
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.MKSearchListener#onGetTransitRouteResult(com.baidu
		 * .mapapi.MKTransitRouteResult, int)
		 */
		public void onGetTransitRouteResult(MKTransitRouteResult arg0, int arg1) {

		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.MKSearchListener#onGetWalkingRouteResult(com.baidu
		 * .mapapi.MKWalkingRouteResult, int)
		 */
		public void onGetWalkingRouteResult(MKWalkingRouteResult arg0, int arg1) {

		}

		@Override
		public void onGetPoiDetailSearchResult(int arg0, int arg1) {

		}

		@Override
		public void onGetRGCShareUrlResult(String arg0, int arg1) {

		}

	};

	/**
	 * process the message
	 * 
	 * @param msg
	 *            the message the message
	 * 
	 * @throws Exception
	 */
	private void processedMessage(Message msg) throws Exception {
		switch (msg.what) {
		case EVENT_TEAM_EXIT:
			// 退出队伍
			exitTeam();
			break;
		case EVENT_TEAM_REFRESH:
			refreshMembers();
			break;
		case EVENT_TEAM_UPDATE:
			updateMembers();
			break;
		case EVENT_TEAM_SEND_LOCATION:
			updateLocation(currentLocation);
			break;
		case EVENT_TEAM_SEND_DEST_NO_ROUTE:
			sendTeamDestination((GeoPoint) msg.obj, false);
			break;
		case EVENT_TEAM_SEND_DEST_WITH_ROUTE:
			sendTeamDestination((GeoPoint) msg.obj, true);
			break;
		case EVENT_TEAM_RECEIVE_LOCATION:
			receiveTeamDestination();
			break;
		case EVENT_CHANGE_CALL_ANIM_ICON:
			if (paused)
				break;
			ImageView iv = (ImageView) findViewById(R.id.recording_animate);
			int pos = ((Integer) msg.obj) % 4;
			iv.setImageResource(anim_icons[pos]);
			break;
		case EVENT_ERROR:
			String errorMessage = ((Exception) msg.obj).getMessage();
			String text = this.getString(R.string.team_error);
			text = text.replace("%1%", errorMessage);
			Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
		}
	}

	/**
	 * refresh the whole team member list from the server.
	 * 
	 * @throws Exception
	 */
	private void refreshMembers() throws Exception {

		// 网络连接的事情应该交给其他线程，而不是主线程去干。
		new Thread() {
			public void run() {
				try {
					TeamProcess process = (TeamProcess) ProcessFactory
							.getProcess(TeamProcess.class);
					final Team team = Team.getCurrentTeam();
					// 更新队员列表
					process.refreshTeamMember(team);

					messageHandler.post(new Runnable() {
						public void run() {
							// 更新图层
							teamMemberOverlay.updateMembers(team);
							// 更新队员列表
							showOrHideMember(showMember);
						}
					});
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}.start();
	}

	/**
	 * update the team member position.
	 * 
	 * @throws Exception
	 */
	private void updateMembers() throws Exception {
		Team team = Team.getCurrentTeam();
		// 更新图层
		teamMemberOverlay.updateMembers(team);
		// 更新队员列表
		showOrHideMember(showMember);
	}

	/**
	 * Exit from the current team.
	 * 
	 * @throws Exception
	 */
	private void exitTeam() throws Exception {
		// 退出队伍
		new Thread() {
			public void run() {
				try {
					TeamProcess process = (TeamProcess) ProcessFactory
							.getProcess(TeamProcess.class);
					process.exitTeam();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}.start();
	}

	/**
	 * Send the location
	 * 
	 * @param location
	 *            the location to send
	 */
	private void updateLocation(Location location) {
		if (location == null)
			return;
		TeamProcess process = (TeamProcess) ProcessFactory
				.getProcess(TeamProcess.class);
		process.sendLocation(location);
	}

	/**
	 * Send the team destination
	 * 
	 * @param geoPoint
	 *            the geopoint of the destination
	 * @param searchRoute
	 *            if caculate the route
	 * @throws Exception
	 */
	private void sendTeamDestination(final GeoPoint geoPoint,
			final boolean searchRoute) throws Exception {
		// 设置目的地
		Team team = Team.getCurrentTeam();
		team.setDestinationLon((float) (geoPoint.getLongitudeE6() / 1E6));
		team.setDestinationLat((float) (geoPoint.getLatitudeE6() / 1E6));
		team.setSearchRoute(searchRoute);

		if (searchRoute)
			searchRoute((float) currentLocation.getLatitude(),
					(float) currentLocation.getLongitude(),
					(float) (geoPoint.getLatitudeE6() / 1E6),
					(float) (geoPoint.getLongitudeE6() / 1E6));
		else
			removeRoute();

		new Thread() {
			/*
			 * (non-Javadoc)
			 * 
			 * @see java.lang.Thread#run()
			 */
			public void run() {
				TeamProcess process = (TeamProcess) ProcessFactory
						.getProcess(TeamProcess.class);
				try {
					process.sendTeamDestination(Team.getCurrentTeam());
					Log.d(TAG, "searchRoute...." + searchRoute);

				} catch (Exception e) {
					Message msg = new Message();
					msg.what = EVENT_ERROR;
					msg.obj = e;
					messageHandler.sendMessage(msg);
				}

			}
		}.start();
	}

	/**
	 * Receiving the team destination
	 * 
	 * @throws Exception
	 */
	private void receiveTeamDestination() throws Exception {
		// 刷新地图
		mapView.invalidate();

		// 设置目的地
		Team team = Team.getCurrentTeam();
		if (team != null && team.isSearchRoute())
			if (!(team.getDestinationLat() == 0 && team.getDestinationLat() == 0))
				searchRoute((float) currentLocation.getLatitude(),
						(float) currentLocation.getLongitude(),
						team.getDestinationLat(), team.getDestinationLon());
		if (team != null && !team.isSearchRoute())
			removeRoute();

		// 屏幕移动至目的地
		if (!(team.getDestinationLat() == 0 && team.getDestinationLat() == 0)) {
			mapController.setCenter(new GeoPoint((int) (team
					.getDestinationLat() * 1E6), (int) (team
					.getDestinationLon() * 1E6)));
		}
	}

	/**
	 * Show or Hide the member list
	 */
	private void showOrHideMember(boolean show) {
		ScrollView scrollView = (ScrollView) findViewById(R.id.team_map_member_sv);
		TextView textView = (TextView) findViewById(R.id.team_map_member_tv);
		// 重置文本
		if (Team.getCurrentTeam() != null) {
			textView.setText(Html.fromHtml(Team.getCurrentTeam()
					.getAllMemberText(currentLocation)));
		}
		// 成员列表的显示、关闭
		scrollView.setVisibility(show ? View.VISIBLE : View.GONE);
	}

	/**
	 * The text timer
	 */
	private volatile Timer hideTimer = null;

	/**
	 * Show or Hide the specific member
	 * 
	 * @param userId
	 *            the user id
	 */
	public void showMember(final int userId) {
		messageHandler.post(new Runnable() {
			public void run() {
				if (hideTimer != null) {
					hideTimer.cancel();
					hideTimer = null;
				}

				hideTimer = new Timer();
				hideTimer.schedule(new TimerTask() {
					public void run() {
						hideMember();
					}
				}, 10000);
				ScrollView scrollView = (ScrollView) findViewById(R.id.team_map_member_sv_float);
				TextView textView = (TextView) findViewById(R.id.team_map_member_tv_float);
				textView.setText(Team.getCurrentTeam().getMemberText(
						currentLocation, userId));
				scrollView.setVisibility(View.VISIBLE);

				Animation ani = new TranslateAnimation(310f, -400f, 0.0f, 0.0f);
				ani.setDuration(10000);
				ani.setRepeatCount(500);
				ani.setRepeatMode(1);
				textView.startAnimation(ani);
			}
		});
	}

	/**
	 * Hide the member list
	 */
	private void hideMember() {
		messageHandler.post(new Runnable() {
			public void run() {
				hideTimer.cancel();
				hideTimer = null;

				// 恢复原来的队名
				ScrollView scrollView = (ScrollView) findViewById(R.id.team_map_member_sv_float);
				TextView textView = (TextView) findViewById(R.id.team_map_member_tv_float);
				if (Team.getCurrentTeam() != null) {
					if (!"".equals(Team.getCurrentTeam().getTeamName())
							&& !Team.getCurrentTeam().getTeamName().equals("")) {
						textView.setText(Team.getCurrentTeam().getTeamName());
					}
				}
				textView.setAnimation(null);
				scrollView.setVisibility(View.VISIBLE);
			}
		});

	}

	/**
	 * Search the route
	 * 
	 * @param startlat
	 *            the start lat
	 * @param startlon
	 *            the start lon
	 * @param endlat
	 *            the end lat
	 * @param endlon
	 *            the end lon
	 */
	private void searchRoute(float startlat, float startlon, float endlat,
			float endlon) {
		Log.d(TAG, "start lat:" + startlat + "start lon:" + startlon);
		Log.d(TAG, "end lat:" + endlat + "end lon:" + endlon);
		// 设置起点
		MKPlanNode start = new MKPlanNode();
		start.pt = new GeoPoint((int) (startlat * 1E6), (int) (startlon * 1E6));
		// 设置终点
		MKPlanNode end = new MKPlanNode();
		end.pt = new GeoPoint((int) (endlat * 1E6), (int) (endlon * 1E6));
		// 计算路线
		mKSearch.setDrivingPolicy(MKSearch.ECAR_TIME_FIRST);
		mKSearch.drivingSearch(null, start, null, end);
	}

	/**
	 * Remove the route
	 * 
	 */
	private void removeRoute() {
		if (routeOverlay != null)
			mapView.getOverlays().remove(routeOverlay);
		mapView.invalidate();
	}

	/**
	 * 检查音量是否调到最大
	 */
	private void checkAudio() {
		AudioManager audioManager = (AudioManager) this
				.getSystemService(Context.AUDIO_SERVICE);
		int currentVolumn = audioManager
				.getStreamVolume(AudioManager.STREAM_MUSIC);
		int maxVolumn = audioManager
				.getStreamMaxVolume(AudioManager.STREAM_MUSIC);

		Log.d(TAG, "currentVolumn--" + currentVolumn);
		Log.d(TAG, "maxVolumn--" + maxVolumn);

		if (currentVolumn < maxVolumn / 2) {
			// 弹出对话框
			AlertDialog.Builder buidler = new AlertDialog.Builder(
					TeamMapActivity.this);
			buidler.setIcon(android.R.drawable.ic_dialog_info);
			buidler.setMessage(R.string.team_check_sound);
			// 按钮 - 是，去到媒体音量设置
			buidler.setPositiveButton(
					TeamMapActivity.this.getString(R.string.team_confirm),
					new OnClickListener() {
						public void onClick(DialogInterface arg0, int arg1) {
							Intent intent = new Intent(
									android.provider.Settings.ACTION_SOUND_SETTINGS);
							TeamMapActivity.this.startActivity(intent);
						}
					});
			// 按钮 - 否
			buidler.setNegativeButton(
					TeamMapActivity.this.getString(R.string.team_cancel),
					new OnClickListener() {
						public void onClick(DialogInterface arg0, int arg1) {
							arg0.dismiss();
						}
					});

			buidler.create().show();
		}
	}

	private int getHeadingIndex(float targetNum) {
		if (targetNum <= 0) {
			return 0;
		} else {
			int intIndex = 0;

			int size = arrayHeading.length - 1;

			if (targetNum > arrayHeading[size]) {
				return size;
			}
			for (int i = 0; i < size; i++) {
				if (targetNum >= arrayHeading[i]
						&& targetNum < arrayHeading[i + 1]) {
					if (Math.abs(arrayHeading[i] - targetNum) > Math
							.abs(arrayHeading[i + 1] - targetNum)) {
						intIndex = i + 1;
					} else {
						intIndex = i;
					}
					break;
				}
			}
			return (intDirection - intIndex);
		}
	}

	/**
	 * 检查GPS是否开启
	 */
	private void checkGPS() {
		LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		boolean gpsOpen = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
		if (!gpsOpen) {
			// 弹出对话框
			AlertDialog.Builder buidler = new AlertDialog.Builder(
					TeamMapActivity.this);
			buidler.setIcon(android.R.drawable.ic_dialog_info);
			buidler.setMessage(R.string.team_check_gps);
			// 按钮 - 是，去到GPS设置
			buidler.setPositiveButton(
					TeamMapActivity.this.getString(R.string.team_confirm),
					new OnClickListener() {
						public void onClick(DialogInterface arg0, int arg1) {
							Intent intent = new Intent(
									android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
							TeamMapActivity.this.startActivity(intent);
						}
					});
			// 按钮 - 否
			buidler.setNegativeButton(
					TeamMapActivity.this.getString(R.string.team_cancel),
					new OnClickListener() {
						public void onClick(DialogInterface arg0, int arg1) {
							arg0.dismiss();
						}
					});
			buidler.create().show();
		}
	}

	/**
	 * The over lay of the team leader
	 * 
	 */
	private class TeamLeaderOverlay extends MyLocationOverlay {
		/**
		 * The paint
		 */
		private Paint paintLine = new Paint();
		/**
		 * The last time sending to server.
		 */
		private long lastUpdateTime;
		/**
		 * The last time sending to server.
		 */
		private Location lastUpdateLocation;
		/**
		 * The minimum duration send the location to server.
		 */
		private static final float MIN_SEND_DURATION = 60 * 1000;
		/**
		 * 
		 * The minimum duration send the location to server.
		 */
		private static final float MIN_SEND_DISTANCE = 25;

		/**
		 * The construtor
		 * 
		 * @param arg0
		 *            the context
		 * @param arg1
		 *            the map view
		 */
		public TeamLeaderOverlay(Context arg0, MapView arg1) {
			super(arg0, arg1);
			paintLine = new Paint();
			paintLine.setARGB(255, 10, 10, 255);
			paintLine.setAntiAlias(true);
			paintLine.setFakeBoldText(true);
			paintLine.setStrokeWidth(2);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.MyLocationOverlay#onLocationChanged(android.location
		 * .Location)
		 */
		public void onLocationChanged(Location location) {
			super.onLocationChanged(location);
			if (location == null)
				return;
			// 更新最新位置
			currentLocation = location;

			// 设置屏幕中心

			if (bupdateMe && mapController != null)
				mapController.setCenter(new GeoPoint((int) (location
						.getLatitude() * 1E6),
						(int) (location.getLongitude() * 1E6)));

			// 当行走一段距离和时间后发送坐标
			long duration = System.currentTimeMillis() - lastUpdateTime;
			float distance = (lastUpdateLocation != null) ? location
					.distanceTo(lastUpdateLocation) : MIN_SEND_DISTANCE + 1;
			// 更新成员列表信息
			if (showMember)
				showOrHideMember(showMember);

			if (duration > MIN_SEND_DURATION || distance > MIN_SEND_DISTANCE) {
				lastUpdateTime = System.currentTimeMillis();
				lastUpdateLocation = location;
//				Toast.makeText(
//						TeamMapActivity.this,
//						"Location: Lat-" + location.getLatitude() + " Lon-"
//								+ location.getLongitude() + " Dir-"
//								+ location.getBearing(), Toast.LENGTH_SHORT)
//						.show();
				updateLocation(location);
			}
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.MyLocationOverlay#drawMyLocation(android.graphics
		 * .Canvas, com.baidu.mapapi.MapView, android.location.Location,
		 * com.baidu.mapapi.GeoPoint, long)
		 */
		protected void drawMyLocation(Canvas canvas, MapView mapView,
				Location lastFix, GeoPoint myLocation, long when) {
			super.drawMyLocation(canvas, mapView, lastFix, myLocation, when);

			Projection projection = mapView.getProjection();
			Point pointMe = new Point();
			projection.toPixels(myLocation, pointMe);
			int headingIndex = getHeadingIndex(lastFix.getBearing());

			// 如果不需要连线，则离开
			if (!line)
				return;
			Team team = Team.getCurrentTeam();
			// 如果没有队员，则离开
			if (team == null)
				return;

			// 连线所有的队员
			for (TeamMember tm : team.getMembers().values()) {
				if (tm.getId() == IMDroid.getUser().getUser_id())
					continue;
				// 如果还没有拿到坐标，忽略
				if (tm.getLat() == 0 || tm.getLon() == 0)
					continue;
				GeoPoint geoPoint = new GeoPoint((int) (tm.getLat() * 1e6),
						(int) (tm.getLon() * 1e6));
				Point pointMember = new Point();
				projection.toPixels(geoPoint, pointMember);
				canvas.drawLine(pointMe.x, pointMe.y, pointMember.x,
						pointMember.y - arrowHeight / 2, paintLine);
			}

			Bitmap bitmap = null;
			if (IMDroid.getUser().getUser_id() == Team.getCurrentTeam()
					.getTeamId()) {
				bitmap = BitmapFactory.decodeResource(getResources(),
						arrow_Me[headingIndex]);
			} else {
				bitmap = BitmapFactory.decodeResource(getResources(),
						arrow_Me_Member[headingIndex]);
			}
			// 重画自己的图标
			int x = pointMe.x - bitmap.getWidth() / 2;
			int y = pointMe.y - bitmap.getHeight() / 2;
			canvas.drawBitmap(bitmap, x, y, new Paint());
		}
	}

	/**
	 * The overlay of team member
	 * 
	 */
	private class TeamMemberOverlay extends ItemizedOverlay<OverlayItem> {
		/**
		 * The paint
		 */
		private Paint paint = new Paint();
		/**
		 * The items
		 */
		private List<OverlayItem> items = new ArrayList<OverlayItem>();
		private static final float MIN_UPDATE_DURATION = 3 * 60 * 1000;
		/**
		 * The marker
		 */
		private Drawable marker = null;

		/**
		 * The resource
		 */
		// private int resourceId;

		/**
		 * The contrustor
		 * 
		 * @param drawable
		 *            the icon drawble
		 * @param context
		 *            the context
		 */
		public TeamMemberOverlay(int resourceId) {
			// 初始化Overlay
			super(boundCenterBottom(TeamMapActivity.this.getResources()
					.getDrawable(resourceId)));
			this.marker = TeamMapActivity.this.getResources().getDrawable(
					resourceId);
			// this.resourceId = resourceId;
			paint.setARGB(255, 10, 10, 255);
			paint.setAntiAlias(true);
			paint.setFakeBoldText(true);
			paint.setTextSize(25);
			paint.setStrokeWidth(3);
			populate();
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.baidu.mapapi.ItemizedOverlay#draw(android.graphics.Canvas,
		 * com.baidu.mapapi.MapView, boolean)
		 */
		public void draw(Canvas canvas, MapView mapView, boolean shadow) {
			// 检查Team
			Team team = Team.getCurrentTeam();
			if (team == null || team.getMembers() == null)
				return;
			// 画上每个team member的名字
			for (TeamMember member : team.getMembers().values()) {
				// 如果是自己，则忽略
				if (member.getId() == IMDroid.getUser().getUser_id())
					continue;
				// 如果还没有拿到坐标，忽略
				if (member.getLat() == 0 || member.getLon() == 0)
					continue;

				Point point = new Point();
				Projection projection = mapView.getProjection();
				GeoPoint geoPoint = new GeoPoint((int) (member.getLat() * 1e6),
						(int) (member.getLon() * 1e6));
				projection.toPixels(geoPoint, point);

				// float textWidth = paint.measureText(member.getDisplayName());
				float textHeight = paint.getTextSize();
				float textCenterX = point.x - 30;
				float textCenterY = point.y - 60 - textHeight;

				if (member.getDeviceType() != null) {
					if (member.getId() == team.getTeamId()) {
						paint.setARGB(255, 212, 73, 8);
					} else {// for team member
						paint.setARGB(255, 2, 2, 209);
					}
				}

				canvas.drawText(member.getDisplayName(), textCenterX,
						textCenterY, paint);
				super.draw(canvas, mapView, shadow);
			}
		}

		/**
		 * Update the team members
		 * 
		 * @param members
		 *            update the members
		 */
		public void updateMembers(Team team) {

			items.clear();
			if (team == null || team.getMembers() == null)
				return;

			for (TeamMember member : team.getMembers().values()) {
				if (member.getLat() == 0 && member.getLon() == 0)
					continue;
				// 如果是自己，则忽略
				if (member.getId() == IMDroid.getUser().getUser_id())
					continue;
				GeoPoint p = new GeoPoint((int) (member.getLat() * 1e6),
						(int) (member.getLon() * 1e6));
				OverlayItem o = new OverlayItem(p, member.getId() + "",
						member.getDisplayName());

				int headingIndex = getHeadingIndex(member.getDirect());
				// for team leader
				if (member.getDeviceType() != null) {
					if (member.getId() == team.getTeamId()) {
						if (member.getDeviceType().equals("1")) {
							marker = arrow_Leader[headingIndex];
						} else {
							marker = arrow_Leader_Lite[headingIndex];
						}
					} else {// for team member
						if (member.getDeviceType().equals("1")) {
							marker = arrow_Member[headingIndex];
						} else {
							marker = arrow_Member_Lite[headingIndex];
						}

					}
				} else {
					marker = arrow_Member[headingIndex];
//					Toast.makeText(TeamMapActivity.this,
//							"getDeviceType is null!", Toast.LENGTH_LONG).show();
				}

				long inter = System.currentTimeMillis()
						- member.getUpdatedTime();
				if (inter > MIN_UPDATE_DURATION) {
					if (member.getDeviceType().equals("1")) {
						marker = getResources().getDrawable(
								R.drawable.arrow_gray);

					} else {
						marker = getResources().getDrawable(
								R.drawable.arrow_lite_gray);
					}
				}

				o.setMarker(boundCenterBottom(marker));
				member.setUpdatedTime(System.currentTimeMillis());

				items.add(o);
			}
			populate();
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.baidu.mapapi.ItemizedOverlay#createItem(int)
		 */
		protected OverlayItem createItem(int i) {
			return items.get(i);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.baidu.mapapi.ItemizedOverlay#size()
		 */
		public int size() {
			return items.size();
		}
	}

	/**
	 * The overlay of destination
	 * 
	 */
	private class DestinationOverlay extends Overlay {
		/**
		 * The paint
		 */
		private Paint paint = new Paint();
		/**
		 * The bitmap
		 */
		private Bitmap bmp = BitmapFactory.decodeResource(IMDroid
				.getAppContext().getResources(), R.drawable.map_car_friend1);

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.baidu.mapapi.Overlay#draw(android.graphics.Canvas,
		 * com.baidu.mapapi.MapView, boolean)
		 */
		public void draw(Canvas canvas, MapView mapView, boolean shadow) {
			Team team = Team.getCurrentTeam();
			if (team != null
					&& !(team.getDestinationLon() == 0 && team
							.getDestinationLat() == 0)) {
				GeoPoint geoPoint = new GeoPoint(
						(int) (team.getDestinationLat() * 1E6),
						(int) (team.getDestinationLon() * 1E6));
				Point point = mapView.getProjection().toPixels(geoPoint, null);

				canvas.drawBitmap(bmp, point.x - bmp.getWidth(),
						point.y - bmp.getHeight(), paint);
			}
		}
	}

	public static void startRecordingAnimation() {
		if (instance != null && instance.animTask != null) {
			instance.animTask.cancel();
			instance.animTask = null;
		}
		if (instance != null) {
			instance.animTask = new TimerTask() {
				long start = System.currentTimeMillis();

				public void run() {
					long passed = System.currentTimeMillis() - start;
					int pos = (int) (passed / 500);
					if (instance != null && instance.getHandler() != null) {
						instance.getHandler()
								.obtainMessage(EVENT_CHANGE_CALL_ANIM_ICON, pos)
								.sendToTarget();
					}
				}
			};
			instance.animTimer.schedule(instance.animTask, 500, 500);
		}

	}

	public static void stopRecordingAnimation() {
		if (instance != null && instance.animTask != null) {
			instance.animTask.cancel();
			instance.animTask = null;
		}
		try {
			Thread.sleep(5);
		} catch (Exception e) {
		}
		if (instance != null) {
			instance.getHandler().obtainMessage(EVENT_CHANGE_CALL_ANIM_ICON, 0)
					.sendToTarget();
		}
	}

	private static class TeamCallHelper {
		/**
		 * The tag to indicate if it is recording
		 */
		public static boolean isRecording = false;
		/**
		 * The tag to indicate if it is stopping
		 */
		public static volatile boolean isStopping = false;
		// 监测录音长度的定时器
		private volatile static Timer recordLengthTimer;
		// 监测录音长度的工作
		private volatile static TimerTask recordLengthTask;

		public static void startRecording() {
			// 已经在录音或停止中，退出
			if (isRecording || isStopping)
				return;

			startRecordingAnimation();
			// 更改状态
			isRecording = true;

			UDPMicrophone.startRecording(new StreamListener() {
				public void onStream(ByteBuffer buf) {
					UDPSendUtilRealtime.sendAudioPack(buf);
				}
			});
			PlaySoundProcess.playSound(PlaySoundProcess.start);

			// 准备录音
			// recorder = new MediaRecorder();
			// recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
			// recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
			// 得到GPS坐标，用于组成文件名字
			// String geo = (currentLocation != null) ? Math
			// .round((currentLocation.getLatitude() * 1000))
			// + "--"
			// + Math.round((currentLocation.getLongitude() * 1000))
			// : "--";

			// 给后缀换个不常用的，以使音乐播放器不自动添加到播放列表 ida = Im-Droid Audio
			// soundFile = IMDroid.TEMP_FOLDER + IMDroid.getUser().getUser_id()
			// + "_" + Team.getCurrentTeam().getTeamId() + "_"
			// + System.currentTimeMillis() + "_" + geo + ".ida";
			//
			// recorder.setOutputFile(soundFile);
			// recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
			// Log.d(TAG, "开始录音: " + soundFile);
			// try {
			// recorder.prepare();
			// } catch (Exception e) {
			// e.printStackTrace();
			// PlaySoundProcess.playSound(PlaySoundProcess.wrong);
			// }
			// recorder.start();
			// PlaySoundProcess.playSound(PlaySoundProcess.start);

			// 准备一分钟计数器
			if (recordLengthTimer == null)
				recordLengthTimer = new Timer();
			recordLengthTask = new TimerTask() {
				public void run() {
					recordLengthTask = null;
					stopRecording();
				}
			};
			recordLengthTimer.schedule(recordLengthTask, 300000);
		}

		/**
		 * Stop record
		 */
		public static void stopRecording() {
			if (!isRecording || isStopping)
				return;

			// 关闭检测时间过长线程
			if (recordLengthTask != null) {
				recordLengthTask.cancel();
				recordLengthTask = null;
			}

			isStopping = true;
			isRecording = false;

			new Thread() {
				public void run() {
					try {
						Thread.sleep(300);
					} catch (Exception e) {
					}
					try {
						UDPMicrophone.stopRecording();
					} catch (Exception e) {
						e.printStackTrace();
					} finally {
						isRecording = false;
					}
					stopRecordingAnimation();
					PlaySoundProcess.playSound(PlaySoundProcess.end);
					isStopping = false;
				}
			}.start();

			// if (recorder == null) {
			// return;
			// }
			// 设置正在STOP的标志位为true
			// isStopping = true;
			//
			// final MediaRecorder myRecorder = recorder;
			// recorder = null;
			// long now = (new Date()).getTime();
			// final boolean shouldSend = (now - recoderTime > 1000);
			//
			// new Thread() {
			// public void run() {
			// // 等一段时间再停止录音，避免漏语音
			// try {
			// Thread.sleep(300);
			// // 停止录音，更新文件
			// myRecorder.stop();
			// PlaySoundProcess.playSound(PlaySoundProcess.end);
			// myRecorder.release();
			// stopRecordingAnimation();
			// // 发送并通知用户
			// if (shouldSend) {
			// TeamProcess process = (TeamProcess) ProcessFactory
			// .getProcess(TeamProcess.class);
			// process.broadcast(soundFile.substring(soundFile
			// .lastIndexOf("/") + 1));
			//
			// // 插入声音列表
			// TeamTalk tt = new TeamTalk();
			// tt.setMemberId(IMDroid.getUser().getUser_id());
			// tt.setMemberName(IMDroid.getUser().getNickname());
			// tt.setFile(soundFile);
			// if (TeamMapActivity.instance != null)
			// TeamMapActivity.instance.getTeamTalks().add(tt);
			//
			// }
			// } catch (Exception e) {
			// PlaySoundProcess.playSound(PlaySoundProcess.wrong);
			// e.printStackTrace();
			// } finally {
			// isStopping = false;
			// }
			// }
			// }.start();
		}
	}
}
